from nameko.rpc import rpc, RpcProxy
from nameko.timer import timer
from nameko.standalone.rpc import ClusterRpcProxy

# import sys
# sys.path.append("..")
from .grid_operation import operation_entry
from .realtime_dispatch_entry import realtime_dispatch_entry
from .dayahead_dispatch_entry import dayahead_dispatch_entry
from .voltage_control_entry import voltage_control_entry

from Common.dbhelper import DBHelper
from Common.models import PvMeta, Device_info, Electric_price, Load_data, PV_forecast, Realtime_commands,Day_Ahead
from Common.settings import *

import json
import random


class ControlService:
    name = 'control_service'

    scada_service_rpc = RpcProxy("scada_service")

    def __init__(self):
        self.dbhelper = DBHelper(conf=None)
        self.session = self.dbhelper.Session()

    # @rpc
    # def grid_control_fun(self):
    #     grid_control = operation_entry.operation_entry()
    #     received_request = self.scada_service_rpc.get_ecode_data()
    #     control_command_str = grid_control.on_process_request(received_request)
    #     print("control_command_result:", control_command_str)
    #
    #     return control_command_str

    @timer(interval=3600)
    def realtime_dispatch(self):
        print("running realtime_dispatch!!")
        if True:
            with ClusterRpcProxy(config) as cluster_rpc:
                received_request = cluster_rpc.scada_service.get_ecode_data()

                print(json.dumps(received_request))

            with open('data.json', 'w', encoding='utf-8') as outfile:
                # json.dump(received_request, outfile)
                print("open file data.json")
                outfile.write(received_request)

            with open("data.json", "r") as read_file:
                input_data = json.load(read_file)
        else:
            with open("real_example_data.json", "r") as read_file:
                input_data = json.load(read_file)

        # related parameters, should be from user interface
        vnorm = dict()
        vnorm["Vnorm"] = 20
        vnorm["X"] = 10
        vnorm["R"] = 20
        microgrid_setting = dict()
        microgrid_setting["MicrogridSetting"] = vnorm
        input_data["Parameters"] = microgrid_setting

        # fetch realtime measurements of pv, load
        with ClusterRpcProxy(config) as cluster_rpc:
            realtime_measurement = cluster_rpc.modbus_service.get_realtime_data()

        temp_measure = dict()
        # for item in realtime_measurement["10102"]:
        #    if int(item['device_id']) == 1:
        #       pv_measure = item['out_active_power']

        pv_measure = random.randint(-100, 100)
        load_measure = random.randint(-100, 100)

        input_data["Measurement"] = {"pv_measure": pv_measure, "load_measure": load_measure}

        print(input_data)

        input_str = json.dumps(input_data)

        # prepare core algorithm module
        grid_control = realtime_dispatch_entry()

        control_commands = grid_control.on_process_request(input_str)

        print(control_commands)

        # call modbus service to send command to hardware

        with ClusterRpcProxy(config) as cluster_rpc:
            backtrack=cluster_rpc.modbus_service.control_in_time.call_async(control_commands)
            data = backtrack.result()

    @timer(interval=3600)
    def dayahead_dispatch(self):
        if True:
            with ClusterRpcProxy(config) as cluster_rpc:
                received_request = cluster_rpc.scada_service.get_ecode_data()

                print(json.dumps(received_request))

            with open('data.json', 'w', encoding='utf-8') as outfile:
                # json.dump(received_request, outfile)
                outfile.write(received_request)

            with open("data.json", "r") as read_file:
                input_data = json.load(read_file)
        else:
            with open("day_example_data.json", "r") as read_file:
                input_data = json.load(read_file)

        # related parameters, should be from user interface
        vnorm = dict()
        vnorm["Vnorm"] = 20

        vnorm["X"] = 10

        vnorm["R"] = 20

        microgrid_setting = dict()
        microgrid_setting["MicrogridSetting"] = vnorm
        input_data["Parameters"] = microgrid_setting

        print(input_data)

        input_str = json.dumps(input_data)

        # prepare core algorithm module
        grid_control = dayahead_dispatch_entry()

        control_command_str = grid_control.on_process_request(input_str)

        print(control_command_str)


class VoltageControlService:
    name = 'voltage_control_service'

    def __init__(self):
        self.dbhelper = DBHelper(conf=None)
        self.session = self.dbhelper.Session()

    @rpc
    def voltage_control(self):
        print("running voltage_control!!!")
        if True:
            with ClusterRpcProxy(config) as cluster_rpc:
                received_request = cluster_rpc.scada_service.get_ecode_data()

                print(json.dumps(received_request))

            with open('data.json', 'w', encoding='utf-8') as outfile:
                # json.dump(received_request, outfile)
                outfile.write(received_request)

            with open("data.json", "r") as read_file:
                input_data = json.load(read_file)
        else:
            with open("vc_example_data.json", "r") as read_file:
                input_data = json.load(read_file)

        # related parameters, should be from user interface
        vnorm = dict()
        vnorm["Vnorm"] = 20

        vnorm["X"] = 10

        vnorm["R"] = 20

        vnorm["pfLimit"] = 0.9

        microgrid_setting = dict()
        microgrid_setting["MicrogridSetting"] = vnorm
        input_data["Parameters"] = microgrid_setting

        print(input_data)

        input_str = json.dumps(input_data)

        # prepare core algorithm module
        grid_control = voltage_control_entry()

        control_commands = grid_control.on_process_request(input_str)

        # print(control_command_str)

        with ClusterRpcProxy(config) as cluster_rpc:
            cluster_rpc.modbus_service.control_in_time(control_commands)


